package AM;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

public class CatchHeroin_Client extends JPanel {

	// 게임 화면 구성에 필요한 객체들
	JPanel card2_north, card2_center, card2_south;
	JPanel card2_west;
	JPanel card2_west_canvas, card2_west_south, card2_west_south_1,
			card2_west_south_2;
	JLabel q_name, q_answer; // 문제명 // 문제정답 text만 들어가고 setEditable을 false로 지정할
								// 것.
	Canvas can;
	JTextField time; // 시간 text만 들어가고 setEditable을 false로 지정할 것.
	JButton del_canvas; // 캔버스 지우기 버튼

	JLabel answer_field_lb, my_nickName; // 정답
	JTextField answer_field_tf; // 정답입력란
	JButton start_bt;// 시작 버튼

	JPanel card2_east, card2_east_south;
	JPanel[] user = new JPanel[4]; // 상대 user에 대한 패널
	JPanel[] user_north = new JPanel[4];
	JPanel[] user_south = new JPanel[4];
	String[] user_nickname = new String[4];
	JLabel[] user_laber_left = new JLabel[4];
	JLabel[] user_laber_right = new JLabel[4];
	JPanel[] user_left = new JPanel[4];
	JPanel[] user_right = new JPanel[4];

	JTextField[] nickname_tf = new JTextField[4]; // 상대 user에 대한 닉네임 레이블
	JTextField[] score_tf = new JTextField[4]; // 상대 user에 대한 스코어 레이블
	JTextField[] whether_good_wrong_tf = new JTextField[4]; // 상대 user에 대한 정답여부
															// 레이블

	JTextField my_score_tf, my_whether_good_wrong_tf;

	// 화면 그리기 x,y좌표
	int x = -30, y;
	Image img;// 캔버스와 크기가 동일한 이미지 객체.
	boolean is_delete_painting = false; // true면 그림 그리기, false면 그림 지우기

	TitledBorder border; // 각 패널들에 대한 타이틀 문구

	// 자원을 주고 받기 위한 객체들
	Socket s;
	ObjectInputStream in;
	ObjectOutputStream out;

	Thread thread;

	JProgressBar pg;
	JLabel status;

	boolean isTurn; // 내턴 여부
	boolean isGaming = false; // 게임진행 여부
	String answer;		// 정답
	boolean isAnswer = false; // 정답 맞췄는지 여부

	String[] question_list = { "집", "직장", "학원", "PC방", "플스방" };

	public CatchHeroin_Client(ObjectOutputStream o) {

		// out 사용 하기 위해 생성자에서 받아서 넣어줌.
		this.out = o;

		setLayout(new BorderLayout());

		card2_north = new JPanel(new FlowLayout(FlowLayout.LEFT));
		card2_north.add(q_name = new JLabel(" "));
		card2_north.add(q_answer = new JLabel(" "));
		// q_answer.setEditable(false);// 문제정답 text만 들어가고 setEditable을 false로
		// 지정할
		// 것.

		card2_west = new JPanel(new BorderLayout());
		card2_west_canvas = new JPanel(new BorderLayout());
		border = new TitledBorder("그림판");
		card2_west_canvas.setBorder(border); // border을 타이틀 명으로 하여 해당 패널에 테두리로
												// 둘러쌓기.
		card2_west_canvas.add(can = new Canvas() {

			@Override
			public void paint(Graphics g) {
				// TODO Auto-generated method stub
				// super.paint(g);
				g.setColor(Color.BLACK);
				if (is_delete_painting) { // 지우기 버튼을 누르면..
					g.setColor(Color.WHITE);
					g.fillRect(0, 0, can.getWidth(), can.getHeight());
					is_delete_painting = false;
				} else {
					g.setColor(Color.BLACK);
					g.fillOval(x, y, 10, 10);

				}

			}

			@Override
			public void update(Graphics g) {
				// TODO Auto-generated method stub
				// super.update(g);
				paint(g);
			}

		});

		can.setBackground(Color.WHITE);

		pg = new JProgressBar();
		pg.setMinimum(0);
		pg.setMaximum(60);
		pg.setValue(0);
		
		JPanel center = new JPanel(new BorderLayout());
	
		card2_west_south = new JPanel(new GridLayout(2, 1));
		card2_west_south_1 = new JPanel(new BorderLayout());
		JPanel card2_west_south_1_east = new JPanel(new FlowLayout(FlowLayout.LEFT));
		
		card2_west_south_1.add(new JLabel("  시간   "), BorderLayout.WEST);
		card2_west_south_1.add(pg);
		
		card2_west_south_1_east.add(status = new JLabel("0/60 sec"));
		card2_west_south_1_east.add(start_bt = new JButton("시작"));
		card2_west_south_1_east.add(del_canvas = new JButton("지우기"));
		
		card2_west_south_1.add(card2_west_south_1_east, BorderLayout.EAST);
		
		card2_west_south.add(card2_west_south_1);

		card2_west_south_2 = new JPanel(new BorderLayout());
		JPanel card2_west_south_1_west = new JPanel(new FlowLayout(FlowLayout.LEFT));
		JPanel card2_west_south_1_center = new JPanel(new FlowLayout(FlowLayout.LEFT));
		
		
		card2_west_south_2.add(answer_field_lb = new JLabel("  정답  "), BorderLayout.WEST);
		card2_west_south_1_center.add(answer_field_tf = new JTextField(31));
		card2_west_south_2.add(card2_west_south_1_center);
		
		card2_west_south_1_west.add(new JLabel("   점 수  "));
		card2_west_south_1_west.add(my_score_tf = new JTextField(7));
		
		card2_west_south_2.add(card2_west_south_1_west, BorderLayout.EAST);
		
//		card2_west_south_2.add(new JLabel("정답 여부:"));
//		card2_west_south_2.add(my_whether_good_wrong_tf = new JTextField(5));
//		card2_west_south_2.add(my_nickName = new JLabel(""));
		card2_west_south.add(card2_west_south_2);

		card2_west.add(card2_west_canvas, BorderLayout.CENTER);

		card2_east = new JPanel(new GridLayout(4, 1));

		for (int i = 0; i < user.length; i++) {
			user[i] = new JPanel(new GridLayout(1, 2));
			
//			user_north[i] = new JPanel();
//			user_south[i] = new JPanel(new FlowLayout(FlowLayout.LEFT));
//
//			user_north[i].add(new JLabel("점수:"));
//			user_north[i].add(score_tf[i] = new JTextField(5));
//			score_tf[i].setEditable(false);
//			user_south[i].add(new JLabel("정답여부:"));
//			user_south[i].add(whether_good_wrong_tf[i] = new JTextField(5));
//			whether_good_wrong_tf[i].setEditable(false);
//			user[i].add(user_north[i]);
//			user[i].add(user_south[i]);
			
			user_left[i] = new JPanel(new BorderLayout());
			user_right[i] = new JPanel(new BorderLayout());
			
			user_left[i].add(new JLabel(" SCORE "), BorderLayout.NORTH);
			user_left[i].add(user_laber_left[i] = new JLabel(""));
			user_laber_left[i].setFont(new Font("굴림", Font.BOLD, 30));
			user[i].add(user_left[i]);
			
			user_right[i].add(new JLabel("CORRECT"), BorderLayout.NORTH);
			user_right[i].add(user_laber_right[i] = new JLabel(""));
			user_laber_right[i].setFont(new Font("굴림", Font.BOLD, 30));
			user[i].add(user_right[i]);

			border = new TitledBorder(user_nickname[i] = ""); 
			// 접속한 클라이언트에 대한 nickname이 들어간다.
			// border을 타이틀 명으로 하여 해당 패널에 테두리로 둘러쌓기.

			user[i].setBorder(border);
			card2_east.add(user[i]);

		}

		card2_center = new JPanel(new BorderLayout());
		card2_center.add(card2_west, BorderLayout.CENTER);
		card2_center.add(card2_east, BorderLayout.EAST);

		add(card2_north, BorderLayout.NORTH);
		add(card2_center, BorderLayout.CENTER);
		add(card2_west_south, BorderLayout.SOUTH);

		can.addMouseMotionListener(new MouseMotionAdapter() {

			@Override
			public void mouseDragged(MouseEvent e) {

				if (!(isTurn && isGaming))
					return;

				CatchHeroin_Client.this.x = e.getX();
				CatchHeroin_Client.this.y = e.getY();
				
//				System.out.println(CatchHeroin_Client.this.x + ","+ CatchHeroin_Client.this.y);
				// drawCanvas(CatchHeroin_Client.this.x,
				// CatchHeroin_Client.this.y);
				
				can.setBackground(Color.WHITE);
				
				// can.repaint(); //프로토콜 연결이 가능해 지면, 이부분 지운다. 어짜피 프로토콜을 서버로 보내면,
				// 다시 전체 프로토콜 수신으로 모든 클라이언트가 갱신하게 된다.

				try {
					Protocol p = new Protocol();
					p.setCmd(Protocol.DRAWING_CANVAS);
					p.setX(CatchHeroin_Client.this.x);
					p.setY(CatchHeroin_Client.this.y);
					CanvasInfo info = new CanvasInfo();
					info.setX(p.getX());
					info.setY(p.getY());
					;
					out.writeObject(p);
				} catch (Exception e2) {
					// TODO: handle exception
					e2.printStackTrace();
				}

			}
		});

		del_canvas.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				
				// TODO Auto-generated method stub
//				System.out.println("del key pressed");
				// cleanCanvas();//프로토콜 연결이 가능해 지면, 이부분 지운다. 어짜피 프로토콜을 서버로 보내면,
				// 다시 전체 프로토콜 수신으로 모든 클라이언트가 갱신하게 된다.
				
				try {
					Protocol p = new Protocol();
					p.setCmd(Protocol.CLEAR_CANVAS);
					out.writeObject(p);
				} catch (Exception e2) {
					// TODO: handle exception
					e2.printStackTrace();
				}

			}
		});

		start_bt.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				
				// TODO Auto-generated method stub
				// 게임을 시작한다
//				System.out.println("Game Start...");
				
				try {
					Protocol p = new Protocol();
					p.setMsg(q_answer.getText());
					p.setCmd(Protocol.GAME_START);
					out.writeObject(p);
				} catch (Exception e2) {
					// TODO: handle exception
					e2.printStackTrace();
				}
			}
		});
		
		answer_field_tf.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				
				String ansewer_tf = answer_field_tf.getText().trim();
				
				if(isGaming && !isAnswer)  {
					if(ansewer_tf.length()>0){
						
						Protocol p = new Protocol();
						p.setCmd(Protocol.SEND_MSG);
						
						if(ansewer_tf.equals(answer)){						
							
							int s = Integer.parseInt(my_score_tf.getText().trim())+1;
							p.setScore(String.valueOf(s));
							p.setMsg("C");
							answer_field_tf.setText("");
							answer_field_tf.setEditable(false);
							isAnswer = true;
							
						}else{
							
							int s = Integer.parseInt(my_score_tf.getText().trim());
							p.setScore(String.valueOf(s));
							p.setMsg("F");
							
							answer_field_tf.setText("");
							
						}
						
						
						try {
							out.writeObject(p);
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					
				}
				
				
			}
		});

		enableFalse();

	}

	/**
	 * 랜덤으로 문제 생성 시킨다.
	 */
	public void randomize_question() {
		int random_number = (int) (Math.random() * 100 + 1); // 1부터 100까지의 정수
																// 난수를 발생시킨다.

		if (random_number >= 0 && random_number < 20)
			q_answer.setText(question_list[0]);
		else if (random_number >= 20 && random_number < 40)
			q_answer.setText(question_list[1]);
		else if (random_number >= 40 && random_number < 60)
			q_answer.setText(question_list[2]);
		else if (random_number >= 60 && random_number < 80)
			q_answer.setText(question_list[3]);
		else if (random_number >= 80 && random_number <= 100)
			q_answer.setText(question_list[4]);

	}

	/**
	 * 정답 입력시 서버로 전달
	 */
	public void send_answer() {
		// 사용자가 입력한 문자열 가져오기
		String msg = answer_field_tf.getText().trim();
		if (msg.length() > 0) {
			// 서버로 전달하기 위한 프로토콜 생성
			Protocol p = new Protocol();
			p.setCmd(Protocol.SEND_MSG);
			p.setMsg(msg);

			try {
				out.writeObject(p);
				answer_field_tf.setText("");
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}

	/**
	 * 캔버스에 그림 그리는 메서드
	 * 
	 * @param x
	 *            : x좌표
	 * @param y
	 *            : y좌표
	 */
	public void drawCanvas(int x, int y) {
		this.x = x;
		this.y = y;
		can.repaint();
		// System.out.println("drawcanvas x = " + this.x + "drawcanvas y = " +
		// this.y);
	}

	/**
	 * 캔버스 그림 지우기
	 */
	public void cleanCanvas() {
		// 이미지 객체를 캔버스 크기와 동일하게 생성.
		is_delete_painting = true;
		this.x = -30;
		this.y = -30;
		can.repaint();

	}

	/**
	 * 클라이언트 정보를 셋팅한다.
	 * 
	 * @param user_list
	 *            : 접속한 유저 정보
	 */
	/*
	 * public void setUserData(ArrayList<User_Info> user_list){
	 * 
	 * }
	 */

	public void enableFalse() {

//		my_whether_good_wrong_tf.setEditable(false);
		my_score_tf.setEditable(false);
		start_bt.setEnabled(false);
		del_canvas.setEnabled(false);
		start_bt.setEnabled(false);
		del_canvas.setEnabled(false);

		answer_field_tf.setEditable(true);
		q_name.setText(" ");
		q_answer.setText(" ");
		pg.setValue(0);
		status.setText("0/60 sec");
		

	}

	/**
	 * 턴 변경시마다 디자인 및 기능 변경
	 */
	public void setTurn() {
		start_bt.setEnabled(true);
		del_canvas.setEnabled(true);
		answer_field_tf.setEditable(false);
		q_name.setText("문 제 : ");
		randomize_question(); // q_answer.setText();
	}

	String nickName;
	public void setUsers(ArrayList<UserInfo> uInfos, String nickName) {
		this.nickName = nickName;
		cleanCanvas();
		enableFalse();
		int i = 0;

		UserInfo temp = new UserInfo();
		temp.setNickName("대기중");
		temp.setScore(0);
		temp.setTurn(false);
		temp.setWhether_good_wrong("-");

		for (UserInfo uInfo : uInfos) {

			if (nickName.equals(uInfo.getNickName())) { // 내정보면
				
				
//				my_nickName.setText(uInfo.getNickName());
//				my_whether_good_wrong_tf.setText(uInfo.getWhether_good_wrong());
				my_score_tf.setText(String.valueOf(uInfo.getScore()));

				border = new TitledBorder(new LineBorder(Color.lightGray, 1),uInfo.getNickName());
				if (uInfo.isTurn()) {
					
					border = new TitledBorder(new LineBorder(Color.BLUE, 3),uInfo.getNickName());
					setTurn();
				}
				
				card2_west_south.setBorder(border);
				this.isTurn = uInfo.isTurn();

			} else {

				border = new TitledBorder(new LineBorder(Color.GRAY, 3),uInfo.getNickName());
				if(uInfo.isTurn()){
					border = new TitledBorder(new LineBorder(Color.BLUE, 3),uInfo.getNickName());
				}
				user[i].setBorder(border);

//				score_tf[i].setText(String.valueOf(uInfo.getScore()));
//				whether_good_wrong_tf[i].setText(uInfo.getWhether_good_wrong());
				user_laber_left[i].setText(" "+String.valueOf(uInfo.getScore()));
				user_laber_right[i].setText(" "+uInfo.getWhether_good_wrong());

				i++;
			}

		}
		
		
		
		if (i < Protocol.CLIENT_MAX_SIZE) {

			for (int k = i; k < Protocol.CLIENT_MAX_SIZE-1; k++) {

				border = new TitledBorder(new LineBorder(Color.lightGray, 1),temp.getNickName());
				user[k].setBorder(border);

//				score_tf[k].setText(String.valueOf(temp.getScore()));
//				whether_good_wrong_tf[k].setText(temp.getWhether_good_wrong());
				
				user_laber_left[k].setText(" "+String.valueOf(temp.getScore()));
				user_laber_right[k].setText(" "+temp.getWhether_good_wrong());


			}
		}

	}
	
	
	
	public void setMsgUser(ArrayList<UserInfo> uInfos, String nickName) {
		int i = 0;

		UserInfo temp = new UserInfo();
		temp.setNickName("대기중");
		temp.setScore(0);
		temp.setTurn(false);
		temp.setWhether_good_wrong("-");
		isAnswer = false;

		for (UserInfo uInfo : uInfos) {

			if (nickName.equals(uInfo.getNickName())) { // 내정보면
				
				
//				my_nickName.setText(uInfo.getNickName());
//				my_whether_good_wrong_tf.setText(uInfo.getWhether_good_wrong());
				my_score_tf.setText(String.valueOf(uInfo.getScore()));

				border = new TitledBorder(new LineBorder(Color.lightGray, 1),uInfo.getNickName());
				if (uInfo.isTurn()) {
					
					border = new TitledBorder(new LineBorder(Color.BLUE, 3),uInfo.getNickName());
					start_bt.setEnabled(true);
					del_canvas.setEnabled(true);
					answer_field_tf.setEditable(false);
				}
				
				card2_west_south.setBorder(border);
				this.isTurn = uInfo.isTurn();

			} else {

				border = new TitledBorder(new LineBorder(Color.GRAY, 3),uInfo.getNickName());
				if(uInfo.isTurn()){
					border = new TitledBorder(new LineBorder(Color.BLUE, 3),uInfo.getNickName());
				}
				user[i].setBorder(border);

//				score_tf[i].setText(String.valueOf(uInfo.getScore()));
//				whether_good_wrong_tf[i].setText(uInfo.getWhether_good_wrong());
				user_laber_left[i].setText(" "+String.valueOf(uInfo.getScore()));
				user_laber_right[i].setText(" "+uInfo.getWhether_good_wrong());

				i++;
			}

		}
		
		
		
		if (i < Protocol.CLIENT_MAX_SIZE) {

			for (int k = i; k < Protocol.CLIENT_MAX_SIZE-1; k++) {

				border = new TitledBorder(new LineBorder(Color.lightGray, 1),temp.getNickName());
				user[k].setBorder(border);

//				score_tf[k].setText(String.valueOf(temp.getScore()));
//				whether_good_wrong_tf[k].setText(temp.getWhether_good_wrong());
				
				user_laber_left[k].setText(" "+String.valueOf(temp.getScore()));
				user_laber_right[k].setText(" "+temp.getWhether_good_wrong());


			}
		}

	}

}
